package com.movie.servie.impl;

import com.api.films.FilmsClient;

import com.movie.es.ESCinema;
import com.movie.es.ESMovie;
import com.movie.servie.IKeywordService;
import com.movie.vo.Result;

import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


import java.util.*;

@Service
public class KeywordService implements IKeywordService {
    @Autowired
    private FilmsClient filmsClient;
    @Autowired
    private ElasticsearchRestTemplate template;

    @Override
    public Result movieKeywordSearch(Map searchMap) {
        //调用远程接口通过关键字搜索从elsticsearch根据moiveName查询获取
        Result result = filmsClient.movieKeywordSearch(searchMap);
        Map data = (Map) result.getData();
        // 调用远程接口通过关键字搜索影人

        //调用远程接口通过关键字搜索电影院
        Result result1 = cinemaKeywordSearch(searchMap);
        Map data1 = (Map) result1.getData();
        List<ESCinema> cinemaList = (List<ESCinema>) data1.get("cinemaList");
        long cinemaTotal = (long) data1.get("cinemaTotal");
        data.put("cinemaList", cinemaList);
        data.put("cinemaTotal", cinemaTotal);
        return new Result(true, "成功", data);
    }

    @Override
    public Result cinemaKeywordSearch(Map searchMap) {
        //1.设置查询条件
        MatchQueryBuilder query = QueryBuilders.matchQuery("cinema_name", searchMap.get("keyword"));
        //2.设置分页
        int page = 0;
        int limit = 5;
        if (!StringUtils.isEmpty(searchMap.get("page"))) {//当前页数
            page = (int) searchMap.get("page");
            page--;
        }
        if (!StringUtils.isEmpty(searchMap.get("limit"))) {//当前页数
            limit = (int) searchMap.get("limit");
        }
        PageRequest pageRequest = PageRequest.of(page, limit);
        //3.设置高亮
        HighlightBuilder highlightBuilder = getHighlightBuilder("cinema_name");
        NativeSearchQuery build = new NativeSearchQueryBuilder()
                .withQuery(query)
                //设置分页
                .withPageable(pageRequest)
                .withHighlightBuilder(highlightBuilder)//设置高亮
                .build();
        SearchHits<ESCinema> res = template.search(build, ESCinema.class);
        //获取当前页信息
        List<ESCinema> cinemaList = new ArrayList<>();
        long totalHits = res.getTotalHits();
        List<SearchHit<ESCinema>> hits = res.getSearchHits();
        hits.forEach(hit -> {
            ESCinema content = hit.getContent();
            //取高亮的信息 将原来的 替换
            Map<String, List<String>> map = hit.getHighlightFields();
            Set<String> keySet = map.keySet();
            keySet.forEach(key -> {
                if (key.equals("cinema_name")) {
                    String s = map.get(key).get(0);
                    content.setCinema_name(s);
                }
            });
            cinemaList.add(content);
        });
        Map map = new HashMap() {{
            put("cinemaList", cinemaList);
            put("cinemaTotal", totalHits);
        }};
        return new Result(true, "成功", map);
    }


    /**
     * 根据关键字查询电影信息
     *
     * @param searchMap
     * @return
     */
    /*@Override
    public Result movieKeywordSearch(Map searchMap) {
        //1.设置查询条件
        MatchQueryBuilder movieName = QueryBuilders.matchQuery("movieName", searchMap.get("keyword"));
        //2.设置分页
        int page = 0;
        int limit = 5;
        if (!StringUtils.isEmpty(searchMap.get("page"))) {//当前页数
            page = (int) searchMap.get("page");
            page--;
        }
        if (!StringUtils.isEmpty(searchMap.get("limit"))) {//当前页数
            limit = (int) searchMap.get("limit");
        }
        PageRequest pageRequest = PageRequest.of(page, limit);
        //3.设置高亮
        HighlightBuilder highlightBuilder = getHighlightBuilder("movieName");
        NativeSearchQuery build = new NativeSearchQueryBuilder()
                .withQuery(movieName)
                //设置分页
                .withPageable(pageRequest)
                .withHighlightBuilder(highlightBuilder)//设置高亮
                .build();
        SearchHits<ESMovie> res = template.search(build, ESMovie.class);
        //获取当前页信息
        List<ESMovie> movieList = new ArrayList<>();
        long totalHits = res.getTotalHits();
        List<SearchHit<ESMovie>> hits = res.getSearchHits();
        hits.forEach(hit -> {
            ESMovie content = hit.getContent();
            //取高亮的信息 将原来的 替换
            Map<String, List<String>> map = hit.getHighlightFields();
            Set<String> keySet = map.keySet();
            keySet.forEach(key -> {
                if (key.equals("movieName")) {
                    String s = map.get(key).get(0);
                    content.setMovieName(s);
                }
            });
            movieList.add(content);
        });
        Map map = new HashMap(){{
            put("movieList",movieList);
            put("movieTotal",totalHits);
        }};
        return new Result(true,"成功",map);
    }

    @Override
    public Result cinemaKeywordSearch(Map searchMap) {
        //1.设置查询条件
        MatchQueryBuilder query = QueryBuilders.matchQuery("cinema_name", searchMap.get("keyword"));
        //2.设置分页
        int page = 0;
        int limit = 5;
        if (!StringUtils.isEmpty(searchMap.get("page"))) {//当前页数
            page = (int) searchMap.get("page");
            page--;
        }
        if (!StringUtils.isEmpty(searchMap.get("limit"))) {//当前页数
            limit = (int) searchMap.get("limit");
        }
        PageRequest pageRequest = PageRequest.of(page, limit);
        //3.设置高亮
        HighlightBuilder highlightBuilder = getHighlightBuilder("cinema_name");
        NativeSearchQuery build = new NativeSearchQueryBuilder()
                .withQuery(query)
                //设置分页
                .withPageable(pageRequest)
                .withHighlightBuilder(highlightBuilder)//设置高亮
                .build();
        SearchHits<ESCinema> res = template.search(build, ESCinema.class);
        //获取当前页信息
        List<ESCinema> cinemaList = new ArrayList<>();
        long totalHits = res.getTotalHits();
        List<SearchHit<ESCinema>> hits = res.getSearchHits();
        hits.forEach(hit -> {
            ESCinema content = hit.getContent();
            //取高亮的信息 将原来的 替换
            Map<String, List<String>> map = hit.getHighlightFields();
            Set<String> keySet = map.keySet();
            keySet.forEach(key -> {
                if (key.equals("cinema_name")) {
                    String s = map.get(key).get(0);
                    content.setCinema_name(s);
                }
            });
            cinemaList.add(content);
        });
        Map map = new HashMap(){{
            put("cinemaList",cinemaList);
            put("cinemaTotal",totalHits);
        }};
        return new Result(true,"成功",map);
    }
    **/


    //设置高亮字段
    private HighlightBuilder getHighlightBuilder(String... fields) {
        // 高亮条件
        HighlightBuilder highlightBuilder = new HighlightBuilder(); //生成高亮查询器
        for (String field : fields) {
            highlightBuilder.field(field);//高亮查询字段
        }
        highlightBuilder.requireFieldMatch(false);     //如果要多个字段高亮,这项要为false
        highlightBuilder.preTags("<span style=\"color:red\">");   //高亮设置
        highlightBuilder.postTags("</span>");
        //下面这两项,如果你要高亮如文字内容等有很多字的字段,必须配置,不然会导致高亮不全,文章内容缺失等
        highlightBuilder.fragmentSize(800000); //最大高亮分片数
        highlightBuilder.numOfFragments(0); //从第一个分片获取高亮片段

        return highlightBuilder;
    }


}
